﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tedds_Tool;
using System.IO;
using System.Collections;
using CommonInterfaces.Models;
using StaticAnalisys;
using LEET.CommonInterfaces.Models;
using Tedds_Tool.Automatables;
using LEET.LEETCommon;

namespace LEET.StaticAnalisys
{
    public class TreeWalker : ITreeWalker
    {
        private IScriptFinder ScriptFinder;
        private IInstructionFactory LEETFactory;

        public TreeWalker(IInstructionFactory factory, IScriptFinder scriptFinder)
        {
            LEETFactory = factory;
            ScriptFinder = scriptFinder;
        }

        // don't trust this to work
        // always use composite to include cyclic detection or you risk 
        // an infinite loop
        public void Traverse(string testName, IVisitor visitor)
        {
            Stack<TextReader> tests = new Stack<TextReader>();
            try
            {
                using(TextReader reader = ScriptFinder.FindTestScript(testName)){
                    tests.Push(reader);
                    INode parent = null;

                    while (tests.Count > 0)
                    {
                        String line;
                        Node node = null;
                        while ((line = tests.Peek().ReadLine()) != null)
                        {
                            IInstruction instruction = LEETFactory.Interpret(line);
                            node = Node.Apply(instruction);
                            node.Parent = parent;
                            visitor.Visit(node);
                            if (node.InstructionType == NodeTypes.EMBED_TYPE)
                            {
                                parent = node;
                                tests.Push(ScriptFinder.FindTestScript(node.Name));
                            }
                        }
                        if (parent != null)
                            parent = parent.Parent;
                        TextReader finished = tests.Pop();
                        finished.Dispose();
                    }
                }
            }
            finally
            {
                while (tests.Count > 0)
                    tests.Pop().Dispose();
            }
            
            
        }
    }
}
